package com.icode.pool;

import java.util.concurrent.*;

import static java.util.concurrent.Executors.defaultThreadFactory;

/**
 * @Author: my_code
 * @Email: my_code@foxmail.com
 * @Create: 2020-12-12 23:17
 * <p>
 * 线程池七大参数
 * new ThreadPoolExecutor(int corePoolSize, //池中要保留的线程数，即使它们处于空闲状态
 * int maximumPoolSize, //池中允许的最大线程数
 * long keepAliveTime,  //当线程数大于核心时，这是多余空闲线程在终止前等待新任务的最长时间。
 * TimeUnit unit,   //关联上一个参数，是其时间单位
 * BlockingQueue<Runnable> workQueue,   //在任务执行前用于保留任务的队列。此队列将只保存{@code execute}方法提交的{@code Runnable}任务。
 * ThreadFactory threadFactory, //执行器创建新线程时要使用的工厂
 * RejectedExecutionHandler handler //当执行被阻塞时要使用的处理程序，因为已达到线程边界和队列容量
 * );
 *
 * 几种边界情况：
 * 1、thread <= core+queue时自会有core线程去处理业务。没有分配的在阻塞队列中等待
 * 2、core+queue < thread < maximumPoolSize时，会由core线程以外的空闲线程去执行业务
 *
 * 四大拒绝策略：
 * 当线程达到最大值，且阻塞队列已满时，还要去线程池中拿线程，即 thread > queue+maximumPoolSize
 *  1、中止策略 AbortPolicy()
 *      抛出：java.util.concurrent.RejectedExecutionException
 *
 *  2、调用者运行策略 CallerRunsPolicy()
 *      由main线程去执行，不会抛出异常
 *
 *  3、放弃最旧的策略
 *      一种被拒绝任务的处理程序，它丢弃最旧的未处理请求，
 *      然后重试{@code execute}，除非执行器关闭，在这种情况下任务被丢弃。
 *
 *  4、放弃策略
 *      被拒绝任务的处理程序，它会自动放弃被拒绝的任务
 *
 *  */
public class Test2 {

    public static void main(String[] args) {

        //获取cpu的核心数
        //System.out.println(Runtime.getRuntime().availableProcessors());
        //此线程池最多可以接收10个线程
        ExecutorService service = new ThreadPoolExecutor(2,
                5,
                2,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5),
                defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());
        try {
            for (int i = 1; i <= 15; i++) {
                final int count = i;
                service.execute(new Thread(() -> {
                    System.out.println("T" + count + ": " + Thread.currentThread().getName());
                }));
            }
        } finally {
            service.shutdown();
        }
    }


}
